package com.woniu.car.advice;
import com.alibaba.fastjson.JSONObject;
import com.woniu.car.config.MyRedisTemplate;
import com.woniu.car.domain.TBackstageAccount;
import com.woniu.car.domain.TRoleUser;
import com.woniu.car.domain.TUrl;
import com.woniu.car.exception.AccountException;
import com.woniu.car.exception.ParamException;
import com.woniu.car.param.*;
import com.woniu.car.service.TBackstageAccountService;
import com.woniu.car.service.TRoleUserService;
import com.woniu.car.service.TUrlService;
import com.woniu.car.util.IsSuper;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@Aspect
@Component
public class AdviceConfig {
    @Resource
    private MyRedisTemplate myRedisTemplate;
    @Resource
    private TRoleUserService tRoleUserService;
    @Resource
    private TUrlService tUrlService;
    @Resource
    private TBackstageAccountService tBackstageAccountService;
    @Before("@annotation(com.woniu.car.annotation.RegisterCode)")
    public void registerCode(JoinPoint joinPoint) throws Exception {
        Object[] args = joinPoint.getArgs();
        UserRegisterParam param = (UserRegisterParam) args[0];
        ValueOperations<String, Object> value = myRedisTemplate.opsForValue();
        Integer code = (Integer) value.get("code:" + param.getUserTel());
        if(null==code){
            throw new ParamException("未向该手机号发送验证码");
        }else {
            String s = code.toString();
            if (!s.equals(param.getCode())) {
                throw new Exception("验证码错误");
            }
        }
    }
    @Before("@annotation(com.woniu.car.annotation.LoginCode)")
    public void loginCode(JoinPoint joinPoint) throws Exception {
        Object[] args = joinPoint.getArgs();
        Object arg = args[0];
        if(arg instanceof UserLoginParam){
            UserLoginParam param=(UserLoginParam) args[0];
            ValueOperations<String, Object> value = myRedisTemplate.opsForValue();
            Integer  code = (Integer) value.get("code:" + param.getUserTel());
            if(null==code){
                throw new ParamException("未向该手机号发送验证码");
            }else {
                String s = code.toString();
                if (!s.equals(param.getCode())) {
                    throw new Exception("验证码错误");
                }
            }
        }else if(arg instanceof UserLoginByCodeParam){
            UserLoginByCodeParam param=(UserLoginByCodeParam) args[0];
            ValueOperations<String, Object> value = myRedisTemplate.opsForValue();
            Integer  code = (Integer) value.get("code:" + param.getUserTel());
            if(null==code){
                throw new ParamException("未向该手机号发送验证码");
            }else {
                String s = code.toString();
                if (!s.equals(param.getCode())) {
                    throw new ParamException("验证码错误");
                }
            }
        }
        else if(arg instanceof ShopLoginParam){
            ShopLoginParam param=(ShopLoginParam) args[0];
            ValueOperations<String, Object> value = myRedisTemplate.opsForValue();
            Integer  code = (Integer) value.get("code:" + param.getShopTel());
            if(null==code){
                throw new ParamException("未向该手机号发送验证码");
            }else {
                String s = code.toString();
                if (!s.equals(param.getCode())) {
                    throw new Exception("验证码错误");
                }
            }
        }

    }
    @Before("@annotation(com.woniu.car.annotation.TelAndPwdCheck)")
    public void TelAndPwdCheck(JoinPoint joinPoint) throws ParamException {
        Object[] args = joinPoint.getArgs();
        Object arg = args[0];
        if(arg instanceof UserLoginByPwdParam){
            UserLoginByPwdParam param=(UserLoginByPwdParam) arg;
                    //电话校验
                this.checkTel(param.getUserTel());
                    //密码校验
            this.checkPwd(param.getUserPwd());
            //密码校验通过
        }else if(arg instanceof ShopLoginParam){
            ShopLoginParam param=(ShopLoginParam) arg;
                    //电话校验
                    this.checkTel(param.getShopTel());
                    //密码校验
                     this.checkPwd(param.getShopPwd());
                    //密码校验通过
        }else if(arg instanceof ShopRegisterParam){
            ShopRegisterParam param=(ShopRegisterParam) arg;

            String tel = param.getShopTel();
            //电话校验
            this.checkTel(tel);
            //密码校验
            this.checkPwd(param.getShopPwd());
        }else if(arg instanceof UserRegisterParam){
            UserRegisterParam param=(UserRegisterParam) arg;
            String code = param.getCode();
            String userTel = param.getUserTel();
            this.checkCode(code,userTel);
            //电话校验
            this.checkTel(userTel);
            //密码校验
          this.checkPwd(param.getUserPwd());
              //密码校验通过
        }
    }

    @Before("@annotation(com.woniu.car.annotation.TelCheck)")
    public void telCheck(JoinPoint joinPoint) throws ParamException {
        Object[] args = joinPoint.getArgs();
        CodeTelParam param = (CodeTelParam) args[0];
        String regex = "^(1[3-9]\\d{9}$)";
        if (param.getTel().length() == 11) {
            Pattern p = Pattern.compile(regex);
            Matcher m = p.matcher(param.getTel());
            //如果手机号匹配
            if (!m.matches()) {
                throw new ParamException("手机号格式不对");
            }
        } else {
            throw new ParamException("电话号码长度不符合要求");
        }
    }
    @Before("@annotation(com.woniu.car.annotation.BackStageAccountCheck)")
    public void backStageAccountCheck(JoinPoint joinPoint) throws ParamException {
        Object[] args = joinPoint.getArgs();
        RegisterBackstageAccountParam param = (RegisterBackstageAccountParam) args[0];
        String backstageAccount = param.getBackstageAccount();
        String backstagePwd = param.getBackstagePwd();
        String regex = "[1-9][0-9]{8,10}";//第一位1-9之间的数字，第二位0-9之间的数字，数字范围4-14个之间
        //String regex2 = "[1-9]\\d{4,14}";//此句也可以
        boolean flag = backstageAccount.matches(regex);
        if(flag){
            this.checkPwd(backstagePwd);
            //密码校验通过，校验创建人
//            Pattern p_str = Pattern.compile("[\\u4e00-\\u9fa5]+");
//            Matcher m = p_str.matcher(param.getRegisterPerson());
//            boolean b = m.find();
//            String group = m.group(0);
//            if(b==false&&group.equals(param.getRegisterPerson())){
//                throw new ParamException("创建人请输入汉字");
//            }
        }else {
            throw new ParamException("账号应为9到10位的数字");
        }
    }
    @Before("@annotation(com.woniu.car.annotation.BackStageLoginCheck)")
    public void backStageLogin(JoinPoint joinPoint) throws ParamException {
        Object[] args = joinPoint.getArgs();
        LoginBackstageAccountParam param = (LoginBackstageAccountParam) args[0];
        String backstageAccount = param.getBackstageAccount();
        String backstagePwd = param.getBackstagePwd();
        String regex = "[1-9][0-9]{8,10}";//第一位1-9之间的数字，第二位0-9之间的数字，数字范围4-14个之间
        boolean flag = backstageAccount.matches(regex);
        if(flag){
            //密码校验通过
           this.checkPwd(backstagePwd);

        }else {
            throw new ParamException("账号应为9到10位的数字");
        }
    }


    //电话号码校验
    public void checkTel(String tel) throws ParamException {
        String regex = "^(1[3-9]\\d{9}$)";
        Pattern p = Pattern.compile(regex);
        Matcher m = p.matcher(tel);
        if(tel.length()==11){
            if(!m.matches()){
                throw new ParamException("手机号码格式不正确");
            }
        }else {
            throw new ParamException("电话号码长度不符合要求");
        }
    }

    //密码校验
    public void checkPwd(String pwd) throws ParamException {
        String regex = "^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z]{8,16}$";
        if(!pwd.matches(regex)) {
            throw new ParamException("密码必须由数字和字母组成，并且要同时含有数字和字母，且长度要在8-16位之间");
        }

    }
    @Before("@annotation(com.woniu.car.annotation.TelAndCodeCheck)")
    public void checkTelAndCode(JoinPoint joinPoint) throws Exception {
        Object[] args = joinPoint.getArgs();
        ShopLoginByCodeParam param = (ShopLoginByCodeParam) args[0];
        String code = param.getCode();
        String tel = param.getShopTel();
        this.checkCode(code,tel);
        this.checkTel(tel);
    }
    //验证码校验
    public void checkCode(String c,String tel) throws ParamException {
        ValueOperations<String, Object> value = myRedisTemplate.opsForValue();
        Integer code = (Integer) value.get("code:" + tel);
        if(null==code){
            throw new ParamException("未向该手机发送验证码");
        }else {
            String s = code.toString();
            System.out.println("C:"+c);
            if (!s.equals(c)) {
                throw new ParamException("验证码错误");
            }
        }
    }

    //后台权限校验
    @Before("@annotation(com.woniu.car.annotation.BackstagePermissionCheck)")
    public void backstagePermissionCheck(JoinPoint joinPoint) throws Exception {
        Object[] args = joinPoint.getArgs();
        HttpServletRequest request=null;
        String uri="";
        for (int i=0;i<args.length;i++){
            if(args[i] instanceof HttpServletRequest){
                request= (HttpServletRequest) args[i];
            }
        }
        String token = request.getHeader("token");
        if(null==token){
            throw new ParamException("缺少token,请输入!");
        }
        //得到后台用户ID
        String i= JWTUtil.getBackId(token);
        System.out.println("用户ID"+i);
        Integer id=Integer.parseInt(i);
        //通过用户ID找到用户,判断是否时超管
        TBackstageAccount tBackstageAccount = new TBackstageAccount();
        tBackstageAccount.setBackstageId(id);
        List<TBackstageAccount> tBackstageAccounts = tBackstageAccountService.queryBackstageAccount(tBackstageAccount);
        for (TBackstageAccount backstageAccount : tBackstageAccounts) {
            System.out.println("isSuper:"+backstageAccount.getIsSuper());
        }
        if(tBackstageAccounts.size()==0){
            throw new AccountException("非法用户，停止访问");
        }else {
            TBackstageAccount tBackstageAccount1 = tBackstageAccounts.get(0);
            Integer isSuper = tBackstageAccount1.getIsSuper();
            System.out.println("isSuper:"+isSuper);
            if(isSuper.equals(IsSuper.NORMAL)){
                System.out.println("进入0");
                uri=request.getRequestURI();
                //通过ID找到角色
                TRoleUser tRoleUser = new TRoleUser();
                tRoleUser.setUserId(id);
                List<TRoleUser> tRoleUsers = tRoleUserService.queryRoleUser(tRoleUser);
                //将用户所拥有的所有角色ID统计
                ArrayList<Integer> integers = new ArrayList<>();
                for (TRoleUser roleUser : tRoleUsers) {
                    integers.add(roleUser.getRoleId());
                }
                //根据当前接口地址查到该方法对应的所有角色ID集合
                TUrl tUrl = new TUrl();
                tUrl.setUrl(uri);
                TUrl tUrl1 = tUrlService.queryUrl(tUrl);
                String roleIds = tUrl1.getRoleIds();
                if(null==roleIds||roleIds.equals("")){
                    System.out.println("进入1");
                    throw new ParamException("您无权访问此功能");
                }else {
                    boolean bool=false;
                    ArrayList<Integer> integers1 = new ArrayList<>();
                    List<UrlRolesJson> urlRolesJsons = JSONObject.parseArray(roleIds, UrlRolesJson.class);
                    for (UrlRolesJson urlRolesJson : urlRolesJsons) {
                        integers1.add(urlRolesJson.getRoleId());
                    }
                    for (Integer integer : integers) {
                        for (Integer integer1 : integers1) {
                            if(integer.equals(integer1)){
                                bool=true;
                                break;
                            }
                        }
                    }
                    if(bool!=true){
                        System.out.println("进入2");
                        throw new ParamException("您无权访问此功能");
                    }
                }
            }
        }
    }


}
